/**
 * 
 * Copyright(c) 2007-2018 Jianjun Jiang <8192542@qq.com>
 * Official site: http://xboot.org
 * Mobile phone: +86-18665388956
 * QQ: 8192542
 *
 * Copyright(c) 2021 Cai_XL <Cai_XL@outlook.com>
 * bilibili : https://space.bilibili.com/54910927
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

 * FIEL: reg.h
 * BRIEF: Definitions of regsiters of F1C100S
 *          Some pieces in this file are taken from u-boot(https://github.com/Lichee-Pi/u-boot.git branch:nano-v2018.01)
 *  imported by gitee(https://gitee.com/wlianmin/u-boot)
 *          Some pieces in this file refer to user manual of 
 *  F1C100S(https://gitee.com/mirrors/business-card-linux/blob/master/doc/F1C100/Allwinner_F1C600_User_Manual_V1.0.pdf),
 * .It's for F1C600, but the business-card-linux used it as doc of F1C100S,and we do so.
 *  
 *  CCU: refer to {business-card-linux}doc/F1C100//Allwinner_F1C600_User_Manual_V1.0.pdf
                  {u-boot}/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
 *      We can find "obj-$(CONFIG_MACH_SUNIV)	+= clock_sun6i.o" in {u-boot}/arch/arm/mach-sunxi/Makefile
 *  so sunxi_ccm_reg defined in sun6i can be used for F1C100S(marked suniv),but here we call it CCU(Clock Control Unit)
 *  instead of CCM(may Clock Control Manager ?) in original file
 *  GPIO: refer to {business-card-linux}doc/F1C100//Allwinner_F1C600_User_Manual_V1.0.pdf
 *  UART: refer to {business-card-linux}doc/F1C100//Allwinner_F1C600_User_Manual_V1.0.pdf
*****************************************************************************/
#ifndef __reg_H
#define __reg_H

#include <stdint.h>

typedef struct
{
    // called pll1_cfg in clock_sun6i.h and PLL_CPU_CTRL_REG in user manual,we use the latter
    volatile uint32_t PLL_CPU_CTRL_REG;             // 0x0000 - 0x0003 PLL_CPU Control Register
    volatile uint32_t Reserved_0;                   // 0x0004 - 0x0007 Not Used
    // called pll2_cfg in clock_sun6i.h and PLL_AUDIO_CTRL_REG in user manual,we use the latter
    volatile uint32_t PLL_AUDIO_CTRL_REG;           // 0x0008 - 0x000b PLL_AUDIO Control Register
    volatile uint32_t Reserved_1;                   // 0x000c - 0x000f Not Used
    // called pll3_cfg in clock_sun6i.h and PLL_VIDEO_CTRL_REG in user manual,we use the latter
    volatile uint32_t PLL_VIDEO_CTRL_REG;        // 0x0010 - 0x0013 PLL_VIDEO Control Register
    volatile uint32_t Reserved_2;                // 0x0014 - 0x0017 Not Used
    // called pll4_cfg in clock_sun6i.h and PLL_VE_CTRL_REG in user manual,we use the latter
    volatile uint32_t PLL_VE_CTRL_REG;           // 0x0018 - 0x001b PLL_VE Control Register
    volatile uint32_t Reserved_3;                // 0x000c - 0x000f Not Used
    // called pll5_cfg in clock_sun6i.h and PLL_DDR_CTRL_REG in user manual,we use the latter
    volatile uint32_t PLL_DDR_CTRL_REG;          // 0x0020 - 0x0023 PLL_DDR Control Register
    volatile uint32_t Reserved_4;                // 0x0024 - 0x0027 Not Used
    // called pll6_cfg in clock_sun6i.h and PLL_PERIPH_CTRL_REG in user manual,we use the latter
    volatile uint32_t PLL_PERIPH_CTRL_REG;       // 0x0028 - 0x002b PLL_PERIPH Control Register
    // pll7_cfg、sata_pll_cfg、pll8_cfg、mipi_pll_cfg、pll9_cfg、pll10_cfg、pll11_cfg not mentioned
    // in the data sheet, may be invalid for F1C100S,so they are reserved.
    volatile uint32_t Reserved_5[9];             // 0x002c - 0x004f Not Used
    // called cpu_axi_cfg in clock_sun6i.h and CPU_CLK_SRC_REG in user manual,we use the latter
    volatile uint32_t CPU_CLK_SRC_REG;           // 0x0050 - 0x0053 CPU Clock Source Register
    // called ahb1_apb1_div in clock_sun6i.h and AHB_APB_HCLKC_CFG_REG in user manual,we use the latter
    volatile uint32_t AHB_APB_HCLKC_CFG_REG;     // 0x0054 - 0x0057 AHB/APB/HCLKC Configuration Register
    // apb2_div、axi_gate not mentioned in the data sheet, may be invalid for F1C100S,so they are reserved.
    volatile uint32_t Reserved_6[2];             // 0x0058 - 0x005f Not Used
    // called ahb_gate0 in clock_sun6i.h and BUS_CLK_GATING_REG0 in user manual,but we call it AHB_CLK_GATING_REG0
    volatile uint32_t AHB_CLK_GATING_REG0;       // 0x0060 - 0x0063 AHB Clock Gating Register 0
    // called ahb_gate1 in clock_sun6i.h and BUS_CLK_GATING_REG1 in user manual,but we call it AHB_CLK_GATING_REG1
    volatile uint32_t AHB_CLK_GATING_REG1;       // 0x0064 - 0x0067 AHB Clock Gating Register 1
    // called apb1_gate in clock_sun6i.h and BUS_CLK_GATING_REG2 in user manual,but we call it APB1_CLK_GATING_REG
    volatile uint32_t APB1_CLK_GATING_REG;       // 0x0068 - 0x006b APB1 Clock Gating Register 2
    // apb2_gate、bus_gate4、nand0_clk_cfg、nand1_clk_cfg not mentioned in the data sheet, 
    // may be invalid for F1C100S,so they are reserved.
    volatile uint32_t Reserved_7[7];             // 0x006c - 0x0087 Not Used
    // called sd0_clk_cfg in clock_sun6i.h and SDMMC0_CLK_REG in user manual,we use the latter
    volatile uint32_t SDMMC0_CLK_REG;            // 0x0088 - 0x008b SDMMC0 Clock Register
    // called sd1_clk_cfg in clock_sun6i.h and SDMMC1_CLK_REG in user manual,we use the latter
    volatile uint32_t SDMMC1_CLK_REG;            // 0x008C - 0x008f SDMMC1 Clock Register
    // sd2_clk_cfg、sd3_clk_cfg、ts_clk_cfg、ss_clk_cfg not mentioned in the data sheet, 
    // may be invalid for F1C100S,so they are reserved.
    volatile uint32_t Reserved_8[4];            // 0x0090 - 0x009f Not Used
    // In data sheet there are two SPIs in datasheet called SPI0 and SPI1, but there are no related clock control regs 
    // in regs of CCU.We still list them because we can find them in clock_sun6i.h,line 53 & 54 ,and name them 
    // SPI0_CLK_REG and SPI1_CLK_REG
    volatile uint32_t SPI0_CLK_REG;             // 0x00a0 - 0x00a3 SPI0 Clock Register 
    volatile uint32_t SPI1_CLK_REG;             // 0x00a4 - 0x00a7 SPI0 Clock Register 
    // spi2_clk_cfg、spi3_clk_cfg not mentioned in the data sheet, 
    // may be invalid for F1C100S,so they are reserved.
    volatile uint32_t Reserved_9[2];            // 0x00a8 - 0x00af Not Used
    // In clock_sun6i.h, the next two reg are called i2s0_clk_cfg and i2s1_clk_cfg.
    // The periphral DAUDIO(= Digital Audio?) is compatible with I2S protocol, so we call it I2S_CLK_REG.
    // The periphral OWA(= One Wire Audio?) is not compatible with I2S protocol for it uses analog signal, 
    // so we keep the name in user manual called OWA_CLK_REG; 
    volatile uint32_t I2S_CLK_REG;              // 0x00B0 - 0x00B3 DAUDIO(I2S protocol) Clock Register
    volatile uint32_t OWA_CLK_REG;              // 0x00B4 - 0x00B7 OWA Clock Register
    // CIR_CLK_REG is reserved in clock_sun6i.h, but we keep it here.
    volatile uint32_t CIR_CLK_REG;              // 0x00B8 - 0X00BB CIR Clock Register
    // spdif_clk_cfg、sata_clk_cfg not mentioned in the data sheet, 
    // may be invalid for F1C100S,so they are reserved.
    volatile uint32_t Reserved_10[4];           // 0x00BC - 0x00CB Not Used
    // called usb_clk_cfg in clock_sun6i.h and USBPHY_CLK_REG in user manual,we use the latter
    volatile uint32_t USBPHY_CLK_REG;           // 0x00CC - 0x00CF USBPHY Clock Register
    volatile uint32_t Reserved_11[9];           // 0x00D0 - 0x00F3 Not Used
    // dram_clk_cfg in clock_sun6i.h is mentioned in user manual, and we call it DRAM_CLK_REG.
    // NOTE: the user manual only gives very limited infomation about DRAM
    volatile uint32_t DRAM_CLK_REG;             // 0x00f4 - 0x00f7 DRAM Clock Control Register
    volatile uint32_t Reserved_12[2];            // 0x00f8 - 0x00ff Not Used
    // called dram_clk_gate in clock_sun6i.h and DRAM_GATING_REG in user manual,we use the latter
    volatile uint32_t DRAM_GATING_REG;           // 0x0100 - 0x0103 DRAM GATING Register
    // called be0_clk_cfg in clock_sun6i.h and BE_CLK_REG in user manual,we use the latter
    volatile uint32_t BE_CLK_REG;                // 0x0104 - 0x0107 BE Clock Register
    // be1_clk_cfg not mentioned in the data sheet, 
    // may be invalid for F1C100S,so they are reserved.
    volatile uint32_t Reserved_13;               // 0x0108 - 0x010b Not Used
    // called fe0_clk_cfg in clock_sun6i.h and FE_CLK_REG in user manual,we use the latter
    volatile uint32_t FE_CLK_REG;                // 0x010C - 0x010f FE Clock Register
    // fe1_clk_cfg、mp_clk_cfg not mentioned in the data sheet, 
    // may be invalid for F1C100S,so they are reserved.
    volatile uint32_t Reserved_14[2];            // 0x0110 - 0x0117 Not Used
    // For next two regs, they are called lcd0_ch0_clk_cfg, lcd0_ch0_clk_cfg in clock_sun6i.h.
    // Acdording ti the user manual, TCON0 is desgined to control LCD timeing and TCON1 is 
    // designed to control TV timing.So we call them TCON0_CLK_REG for TCON0 and TCON1_CLK_REG 
    // for TCON1 instead of TCON_CLK_REG and DI_CLK_REG
    volatile uint32_t TCON0_CLK_REG;            // 0x0118 - 0x011b TCON0 Clock Register
    volatile uint32_t TCON1_CLK_REG;            // 0x011C - 0x011f TCON1 Clock Register
    // called tve_clk_cfg in clock_sun6i.h and TVE_CLK_REG in user manual,we use the latter
    volatile uint32_t TVE_CLK_REG;              // 0x0120 - 0x0123 TVE Clock Register
    // Not mentioned in clock_sun6i.h, so we keep it.
    volatile uint32_t TVD_CLK_REG;               // 0x0124 - 0x0127 TVD Clock Register
    volatile uint32_t Reserved_15[3];            // 0x0128 - 0x0133 Not Used
    // called csi0_clk_cfg in clock_sun6i.h and CSI_CLK_REG in user manual,but we call it CSI0_CLK_REG
    volatile uint32_t CSI0_CLK_REG;               // 0x0134 - 0x0137 CSI Clock Register
    // csi1_clk_cfg not mentioned in the data sheet, 
    // may be invalid for F1C100S,so they are reserved.
    volatile uint32_t Reserved_16;               // 0x0138 - 0x013B Not Used
    // called ve_clk_cfg in clock_sun6i.h and VE_CLK_REG in user manual,we use the latter
    volatile uint32_t VE_CLK_REG;                // 0x013C - 0x013f VE Clock Register
    // called adda_clk_cfg in clock_sun6i.h and AUDIO_CODEC_CLK_REG in user manual,we use the latter
    volatile uint32_t AUDIO_CODEC_CLK_REG;       // 0x0140 - 0x0143 Audio Codec Clock Register
    // called avs_clk_cfg in clock_sun6i.h and AVS_CLK_REG in user manual,we use the latter
    volatile uint32_t AVS_CLK_REG;               // 0x0144 - 0x0147 AVS Clock Register
    // A lot of regs are reserved.
    volatile uint32_t Reserved_17[46];           // 0x0148 - 0x01ff Not Used
    // called pll_lock in clock_sun6i.h and PLL_STABLE_TIME_REG0 in user manual,but we call it PLL_GLOBAL_TIME_REG
    volatile uint32_t PLL_GLOBAL_TIME_REG;      // 0x0200 - 0x0203 PLL Stable Time Register 0
    // called pll1_lock in clock_sun6i.h and PLL_STABLE_TIME_REG1 in user manual,but we call it PLL_CPU_TIME_REG
    volatile uint32_t PLL_CPU_TIME_REG;        // 0x0204 - 0x0207 PLL Stable Time Register 1
    // Not used in user manual or user manual
    volatile uint32_t Reserved_18[6];            // 0x0208 - 0x021f Not Used
    // called pll1_bias_cfg in clock_sun6i.h and PLL_CPU_BIAS_REG in user manual,we use the latter
    volatile uint32_t PLL_CPU_BIAS_REG;          // 0x0220 - 0x0223 PLL_CPU Bias Register
    // called pll2_bias_cfg in clock_sun6i.h and PLL_AUDIO_BIAS_REG in user manual,we use the latter
    volatile uint32_t PLL_AUDIO_BIAS_REG;        // 0x0224 - 0x0227 PLL_AUDIO Bias Register
    // called pll3_bias_cfg in clock_sun6i.h and PLL_VIDEO_BIAS_REG in user manual,we use the latter
    volatile uint32_t PLL_VIDEO_BIAS_REG;        // 0x0228 - 0x022b PLL_VIDEO Bias Register
    // called pll4_bias_cfg in clock_sun6i.h and PLL_VE_BIAS_REG in user manual,we use the latter
    volatile uint32_t PLL_VE_BIAS_REG;           // 0x022C - 0x022f PLL_VE Bias Register
    // called pll5_bias_cfg in clock_sun6i.h and PLL_DDR_BIAS_REG in user manual,we use the latter
    volatile uint32_t PLL_DDR_BIAS_REG;          // 0x0230 - 0x0233 PLL_DDR Bias Register
    // called pll6_bias_cfg in clock_sun6i.h and PLL_PERIPH_BIAS_REG in user manual,we use the latter
    volatile uint32_t PLL_PERIPH_BIAS_REG;       // 0x0234 - 0x0237 PLL_PERIPH Bias Register
    // A lot of regs are reserved.
    volatile uint32_t Reserved_19[6];            // 0x0238 - 0x024f Not Used
    // Not mentioned in clock_sun6i.h, so ew keep it.
    volatile uint32_t PLL_CPU_TUN_REG;           // 0x0250 - 0x0253 PLL_CPU Tuning Register
    // A lot of regs are reserved.
    volatile uint32_t Reserved_20[3];            // 0x0254 - 0x025f Not Used
    // called pll5_tuning_cfg in clock_sun6i.h and PLL_DDR_TUN_REG in user manual,we use the latter
    volatile uint32_t PLL_DDR_TUN_REG;           // 0x0260 - 0x0263 PLL_DDR Tuning Register
    // A lot of regs are reserved.
    volatile uint32_t Reserved_21[8];            // 0x0264 - 0x0283 Not Used
    // called pll2_pattern_cfg in clock_sun6i.h and PLL_AUDIO_PAT_CTRL_REG in user manual,we use the latter
    volatile uint32_t PLL_AUDIO_PAT_CTRL_REG;    // 0x0284 - 0x0287 PLL_AUDIO Pattern Control Register
    // called pll3_pattern_cfg in clock_sun6i.h and PLL_VIDEO_PAT_CTRL_REG in user manual,we use the latter
    volatile uint32_t PLL_VIDEO_PAT_CTRL_REG;    // 0x0288 - 0x028b PLL_VIDEO Pattern Control Register
    // The reg are reserved.
    volatile uint32_t Reserved_22;               // 0x028c - 0x028f Not Used
    // called pll5_pattern_cfg in clock_sun6i.h and PLL_DDR_PAT_CTRL_REG in user manual,we use the latter
    volatile uint32_t PLL_DDR_PAT_CTRL_REG;      // 0x0290 - 0x0293 PLL_DDR Pattern Control Register
    // A lot of regs are reserved.
    volatile uint32_t Reserved_23[11];           // 0x0294 - 0x02bf Not Used
    // called ahb_reset0_cfg in clock_sun6i.h and BUS_SOFT_RST_REG0 in user manual,but we call it AHB_SOFT_RST_REG0
    volatile uint32_t AHB_SOFT_RST_REG0;         // 0x02C0 - 0x02c3 Bus Software Reset Register 0
    // called ahb_reset1_cfg in clock_sun6i.h and BUS_SOFT_RST_REG1 in user manual,but we call it AHB_SOFT_RST_REG1
    volatile uint32_t AHB_SOFT_RST_REG1;         // 0x02C4 - 0x02c7 Bus Software Reset Register 1
    // A lot of regs are reserved.
    volatile uint32_t Reserved_24[2];            // 0x02c8 - 0x02cf Not Used
    // called apb1_reset_cfg in clock_sun6i.h and BUS_SOFT_RST_REG2 in user manual,but we call it APB1_SOFT_RST_REG
    volatile uint32_t APB1_SOFT_RST_REG;         // 0x02D0 - 0x02d3 Bus Software Reset Register 2
    /***********
     * NOTE:
     *      PLL1 -> PLL_CPU
     *      PLL2 -> PLL_AUDIO
     *      PLL3 -> PLL_VIDEO
     *      PLL4 -> PLL_VE
     *      PLL5 -> PLL_DDR
     *      PLL6 -> PLL_PERIPH
    */
}CCU_TypeDef;

typedef struct
{
    volatile uint32_t Pn_CFG0;  // 0x0000-0x0003 GPIO Config 0
    volatile uint32_t Pn_CFG1;  // 0x0004-0x0007 GPIO Config 1
    volatile uint32_t Pn_CFG2;  // 0x0008-0x000b GPIO Config 2
    volatile uint32_t Pn_CFG3;  // 0x000c-0x000f GPIO Config 3
    volatile uint32_t Pn_DATA;  // 0x0010-0x0013 GPIO Data
    volatile uint32_t Pn_DRV0;  // 0x0014-0x0017 GPIO Drive Level 0
    volatile uint32_t Pn_DRV1;  // 0x0018-0x001b GPIO Drive Level 1
    volatile uint32_t Pn_PUL0;  // 0x001c-0x001f GPIO Pull-up and Pull-down control 0
    volatile uint32_t Pn_PUL1;  // 0x0020-0x0023 GPIO Pull-up and Pull-down control 1
}GPIO_TypeDef;


typedef struct
{
    union 
    {
        // valid only if UART_LCR_REG::DR is set
        volatile uint32_t UART_RBR_REG; // 0x0000 - 0x0003 UART Receive Buffer Register
        // writable only if UART_LSR_REG::THRE(bit5) is set
        volatile uint32_t UART_THR_REG; // 0x0000 - 0x0003 UART Transmit Holding Register
        // accessable only if UART_LCR_REG::DLAB(bit7) is set and UART_USR_REG::BUSY(bit0) is zero
        volatile uint32_t UART_DLL_REG; // 0x0000 - 0x0003 UART Divisor Latch Low Register
    } Group1;
    union
    {
        // accessable only if UART_LCR_REG::DLAB(bit7) is set and UART_USR_REG::BUSY(bit0) is zero
        volatile uint32_t UART_DLH_REG; // 0x0004 - 0x0007 UART Divisor Latch High Register
        // accessable only if UART_LCR_REG::DLAB(bit7) is zero ?
        volatile uint32_t UART_IER_REG; // 0x0004 - 0x0007 UART Interrupt Enable Register
    }Group2;
    union
    {
        // reads return the value of UART_IIR_REG
        volatile uint32_t UART_IIR_REG; // 0x0008 - 0x000b UART Interrupt Identity Register
        // writtings access to UART_FCR_REG
        volatile uint32_t UART_FCR_REG; // 0x0008 - 0x000b UART FIFO Control Register
    }Group3;
    volatile uint32_t UART_LCR_REG;     // 0x000C - 0x000f UART Line Control Register
    volatile uint32_t UART_MCR_REG;     // 0x0010 - 0x0013 UART Modem Control Register
    volatile uint32_t UART_LSR_REG;     // 0x0014 - 0x0017 UART Line Status Register
    volatile uint32_t UART_MSR_REG;     // 0x0018 - 0x001b UART Modem Status Register
    volatile uint32_t UART_SCH_REG;     // 0x001C - 0x001f UART Scratch Register
    uint32_t Reserved_1[23];            // 0x0020 - 0x007b
    volatile uint32_t UART_USR_REG;     // 0x007C - 0x007f UART Status Register
    volatile uint32_t UART_TFL_REG;     // 0x0080 - 0x0083 UART Transmit FIFO Level Register
    volatile uint32_t UART_RFL_REG;     // 0x0084 - 0x0087 UART Receive FIFO Level Register
    volatile uint32_t UART_HSK_REG;     // 0x0088 - 0x008b UART DMA Handshake Config Register
    uint32_t Reserved_2[6];             // 0x008c - 0x00a3
    volatile uint32_t UART_HALT_REG;    // 0x00A4 - 0x00a7 UART Halt TX Register
    uint32_t Reserved_3[2];             // 0x00a8 - 0x00af
    volatile uint32_t UART_DBG_DLL_REG; // 0x00b0 - 0x00b3 UART Debug DLL Register
    volatile uint32_t UART_DBG_DLH_REG; // 0x00b4 - 0x00b7 UART Debug DLH Register
}UART_TypeDef;

#define CCU_BASEADDRESS     0x01C20000
#define GPIO_BSASEADDRESS   0x01c20800
#define GPIO0_BASEADDRESS   (GPIO_BSASEADDRESS+0x24*0)
#define GPIO1_BASEADDRESS   (GPIO_BSASEADDRESS+0x24*1)
#define GPIO2_BASEADDRESS   (GPIO_BSASEADDRESS+0x24*2)
#define GPIO3_BASEADDRESS   (GPIO_BSASEADDRESS+0x24*3)
#define GPIO4_BASEADDRESS   (GPIO_BSASEADDRESS+0x24*4)
#define GPIO5_BASEADDRESS   (GPIO_BSASEADDRESS+0x24*5)
#define UART0_BASEADDRESS   (0x01c25000)
#define UART1_BASEADDRESS   (0x01c25400)
#define UART2_BASEADDRESS   (0x01c25800)

#define CCU     ((CCU_TypeDef*)CCU_BASEADDRESS)
#define GPIO0   ((GPIO_TypeDef*)GPIO0_BASEADDRESS)
#define GPIO1   ((GPIO_TypeDef*)GPIO1_BASEADDRESS)
#define GPIO2   ((GPIO_TypeDef*)GPIO2_BASEADDRESS)
#define GPIO3   ((GPIO_TypeDef*)GPIO3_BASEADDRESS)
#define GPIO4   ((GPIO_TypeDef*)GPIO4_BASEADDRESS)
#define GPIO5   ((GPIO_TypeDef*)GPIO5_BASEADDRESS)
#define GPIOA   GPIO0
#define GPIOB   GPIO1
#define GPIOC   GPIO2
#define GPIOD   GPIO3
#define GPIOE   GPIO4
#define GPIOF   GPIO5
#define UART0   ((UART_TypeDef*)UART0_BASEADDRESS)
#define UART1   ((UART_TypeDef*)UART1_BASEADDRESS)
#define UART2   ((UART_TypeDef*)UART2_BASEADDRESS)

#endif
